Restore sync stream after enable_module() re-enables a direction - #2
Open
wormuz wants to merge 2 commits into
Open
Restore sync stream after enable_module() re-enables a direction#2wormuz wants to merge 2 commits into
wormuz wants to merge 2 commits into
Conversation
libbladeRF tears down the synchronous stream when a direction is
disabled: rfic_host.c calls sync_deinit() on !dir_enable, and bladerf1.c
does the same. That is documented ("this will shut down the underlying
asynchronous stream when enable = false"), but re-enabling the module
does not bring the stream back.
Every later sync_tx()/sync_rx() then fails with
sync tx invalid: not initialized
which gives no hint that sync_config() must be repeated. From the
caller's side the radio simply looks dead: measured on a TX1 -> 50 dB
pad -> RX1 loopback, the received level stopped responding to TX gain
(60 dB and -30 dB both gave -44.4 dB) and 65487 of 66033 transmit calls
failed.
Remember the last sync_config() arguments per direction and replay them
when the module is enabled again. Direction is taken from the low bit:
TX channels are 1 and 3, TX layouts are 1 and 3, RX are even.
Verified on hardware: the disable -> enable -> sync_tx sequence went from
ERR_INVAL to OK, and transmit errors dropped from 65487 to 0.
A stream configured with a *_META format carries per-buffer timestamps and flags. Passing metadata=None leaves libbladeRF with nowhere to report them, so the caller silently loses the timestamp it needs and bladerf_get_timestamp() keeps returning 0. Nothing in the error path points at the cause, so this reads as dead hardware rather than a mismatched call. Measured on a TX1 -> 50 dB pad -> RX1 loopback at 15.36 MSps: with the stream in a metadata format but metadata=None, the frame timestamp stayed at 762229041 across 8 consecutive reads and get_timestamp() returned 0. Consecutive gain steps then analysed the same buffer, so the receive level repeated in pairs (-34.9/-34.9, -20.2/-20.2 dBFS) and a gain ladder that is in fact monotonic came out looking broken. The stream format is already remembered per direction for the enable_module restore path, so the check costs nothing extra: sync_rx()/sync_tx() now raise instead of losing timestamps quietly. After fixing the call sites the same ladder is monotonic, with deviations of +0.1 to +0.8 dB over a 40 dB span.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
libbladeRF tears down the synchronous stream when a direction is disabled:
rfic_host.ccallssync_deinit()on!dir_enable, andbladerf1.cdoes the same. That is documented behaviour — the header says "this will shut down the underlying asynchronous stream whenenable= false" — but re-enabling the module does not bring the stream back.Every later
sync_tx()/sync_rx()then fails withwhich gives no hint that
sync_config()has to be repeated.How it looks from the caller side
The radio simply appears dead. Measured on a TX1 → 50 dB pad → RX1 loopback:
Nothing in the error text points at
enable_module()as the cause, so this reads as broken hardware rather than a lifecycle contract.Fix
Remember the last
sync_config()arguments per direction and replay them when the module is enabled again.Direction is taken from the low bit: TX channels are 1 and 3, TX layouts are 1 and 3, RX are even — verified against the enum values on device.
Verification
On hardware, the previously failing sequence:
became:
and transmit errors over a full probe run dropped from 65487 to 0.